package async_op

import (
	"sync/atomic"

	"xgame.go_server/comm/log"
	"xgame.go_server/comm/main_thread"
)

// 工人、苦力、搬砖的...
type worker struct {
	// 任务队列
	taskQ chan func()
	// 已开始
	started int32
}

// 处理异步操作,
// 只是将异步操作和继续执行过程加入到队列里,
// 并不是立即就处理...
// asyncOp = 异步操作函数
// continueWith = 继续执行过程, 将在主线程中调用
func (this *worker) process(asyncOp func(), continueWith func()) {
	if nil == asyncOp {
		log.Warning("异步操作为空")
		return
	}

	if nil == this.taskQ {
		log.Error("任务队列尚未初始化")
		return
	}

	// 将 asyncOp 和 continueWith 包装成一个新函数,
	// 插入到任务队列...
	this.taskQ <- func() {
		// 执行异步操作
		asyncOp()

		if nil != continueWith {
			// 通过主线程继续执行
			main_thread.Process(continueWith)
		}
	}

	if atomic.CompareAndSwapInt32(&this.started, 0, 1) {
		// 开始循环执行任务
		this.startLoopExecTask()
	}
}

// 循环执行任务
func (this *worker) startLoopExecTask() {
	go this.loopExecTask()
}

// 循环执行任务
func (this *worker) loopExecTask() {
	for {
		task := <-this.taskQ

		if nil == task {
			continue
		}

		func() {
			defer func() { // 类似于 try
				if err := recover(); nil != err { // 类似于 catch
					log.Error("发生异常, %+v", err)
				}
			}()

			// 执行任务
			task()
		}()
	}
}
